package com.gopay.bis.tbank.ebank.operation;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.tbank.ebank.query.res.TBankBodyRes;
import com.gopay.common.domain.bank.tbank.ebank.query.res.TBankHeaderRes;
import com.gopay.common.domain.bank.tbank.ebank.query.res.TBankOrderRes;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.HttpsTransport;


/**
 * 测试银行B2B订单查询
 * @TBankB2bQuery.java
 * @author WangHongFei
 *
 */
public class TBankB2bQuery {	
	private HttpsTransport httpsTransport;
	
	/**
	 * 发起请求
	 */
	public Object submit(Map<String, String> map, String bankUrl) throws GopayException{
		BaseMessage baseMessage = new BaseMessage();
		baseMessage.setOutStlmCd(BankConstants.BANK_LOGO_TBANK); // 为了根据银行区分日志输出
		try {
			httpsTransport.setUrl(bankUrl);
			BankLogUtils.printB2BQuerySendLog(baseMessage, map);
			Object messageData = httpsTransport.submit(map);
			BankLogUtils.printB2BQueryBlackLog(baseMessage, ToStringBuilder.reflectionToString(messageData));
			return messageData;
		} catch (Exception e) {
			BankLogUtils.printB2BQueryExceptionLog(baseMessage, e);
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6036);
		}
	}
	
	/**
	 * 解析回应数据
	 */
	public TBankOrderRes parse(Object receivedMsgData) throws GopayException{
		BaseMessage baseMessage = new BaseMessage();
		baseMessage.setOutStlmCd(BankConstants.BANK_LOGO_TBANK); // 为了根据银行区分日志输出
		try{
			if(receivedMsgData == null){
				return null;
			}
			
			TBankOrderRes ret = new TBankOrderRes();
			List orders = new ArrayList();
			TBankHeaderRes header = null;// 报文头
			
			//解析XML报文
			Document document = getDocumentByReceivedMsg(receivedMsgData);
			Element resultEle = document.getRootElement();
			
			// 处理报文头信息
			Element headerEle = resultEle.element("header");
			if(headerEle != null){
				header = new TBankHeaderRes();
				parseElement(headerEle, header);
			}
			// 处理报文体
			Element bodyEle = resultEle.element("body");
			if(bodyEle != null){
				Element ordersEle = bodyEle.element("orders");
				if(ordersEle != null){
					// 获得body下所有的orderTrans标签
					for(Iterator iter = ordersEle.elementIterator("order");iter.hasNext();){
						Element order = (Element) iter.next();
						TBankBodyRes body = new TBankBodyRes();
						// 获得每个orderTrans下的所有标签，并赋值平台数据对象中
						parseElement(order, body);
						orders.add(body);
					}
				}
			}		
			ret.setHeader(header);
			ret.setOrders(orders);
			return ret;
		}catch(Exception e){
			BankLogUtils.printB2BQueryExceptionLog(baseMessage, e);
			throw new GopayException(ProcCodeConstants.PROC_CODE_100E6038);
		}
	}
	
	/**
	 * 解析元素e，并将值赋值到obj中
	 * @param Element
	 * @param Object
	 */
	private void parseElement(Element e, Object obj) throws Exception{
		BeanWrapper bw = new BeanWrapperImpl(obj);
		// 获得元素e下的所有子元素，并赋值到obj中
		for(Iterator it = e.elementIterator();it.hasNext();){
			Element eChild = (Element) it.next();
			String eName = eChild.getName().trim();// 元素名--属性名
			String value = eChild.getText().trim();// 元素eName的值--属性值
			bw.setPropertyValue(eName, value);
		}
	}
	
	/**
	 * 解析模拟银行回应的数据为Document并返回
	 * @param Object
	 * @return Document
	 */
	private Document getDocumentByReceivedMsg(Object receivedMsgData) throws Exception{
		BaseMessage baseMessage = new BaseMessage();
		baseMessage.setOutStlmCd(BankConstants.BANK_LOGO_TBANK); // 为了根据银行区分日志输出
		String xmlData = null;
		
		if (receivedMsgData instanceof byte[]) {
			xmlData = new String((byte[]) receivedMsgData, "UTF-8");
		} else if (receivedMsgData instanceof String) {
			xmlData = (String) receivedMsgData;
		}
		BankLogUtils.printB2BQueryBlackLog(baseMessage, xmlData);
		Document document = null;
		document = DocumentHelper.parseText(xmlData);
		return document;
	}

	public void setHttpsTransport(HttpsTransport httpsTransport) {
		this.httpsTransport = httpsTransport;
	}	

}
